package edzest.basic;

public class J15_Interface {

	public static void main(String[] args) {
		// J15SungJukService sjsrv = new J15SungJukService();
		// new J15SungJukService();밑에 아래 에러메시지 뜸
		// Cannot instantiate the type J15SungJukService
		// 인터페이스는 new 연산자를 통해 객체로 만들 수 없음
		// 반드시 이것을 상속(구현)한 클래스를 
		// 통해 객체로 생성할 수 있음
		J15SungJukServiceImpl sjsrv = new J15SungJukServiceImpl();
		// 성적처리에 필요한 기능(총점메서드, 평균메서드, 학점메서드)들을
		// 인터페이스로 분리해서 추상메서드로 정의하고
		// 그것을 구현implements해서 클래스로 작성
		// J15SungJukService(인터페이스) 
		//	-> J15SungJukServiceImpl(구현클래스)
		
		J15SungJukVO s = new J15SungJukVO("지현", 98, 87, 99);
		s.setTot( sjsrv.getTotal(s) );
		s.setAvg( sjsrv.getAverage(s) );
		s.setGrd( sjsrv.getGrade(s) );
		// 게터세터 클래스에서 국어,영어,수학 점수 가져와서 (s)
		// 여기 인터페이스  총점, 평균, 학점메서드에서 총점, 평균, 학점 계산후
		// 다시 게터세터 클래스에서 각 변수에 값 저장 setTot..
		
		System.out.println( s.toString() );
	}

}

// 인터페이스 정의 (~Service)
interface J15SungJukService {
	// 인터페이스가 제공할 메서드 정의
	// 메서드는 서명까지만 작성
	// 이러한 메서드를 추상메서드라 함
	
	// 인터페이스: 어차피 클래스의 메서드는 서브클래스에서 
	// 오버라이드 안쓰이므로
	// 메서드만 인터페이스에 몰아서 정의함
	
	// int getTotal( int kor, int eng, int mat );
	// 이렇게 매개변수를 일일히 넣을려면 힘들다
	// 그래서 아래처럼 변수들의 묶음이자 자료형인 클래스를 매개변수로 받으면 편함
	
	// private int aaa;
	// Illegal modifier for the interface field J15SungJukService.aaa; 
	// only public, static & final are permitted
	
	int getTotal( J15SungJukVO sj );
	double getAverage( J15SungJukVO sj );
	char getGrade( J15SungJukVO sj );
	// 게터세터 클래스에서 국어,영어,수학 점수 가져와서
	// 여기 인터페이스  총점, 평균, 학점메서드에서 총점, 평균, 학점 계산
}

// 인터페이스를 구현한 클래스 작성(~Impl : ~를 구현한 클래스라는 뜻)
class J15SungJukServiceImpl implements J15SungJukService {

	@Override
	public int getTotal(J15SungJukVO sj) {
		int tot = sj.getKor() + sj.getEng() + sj.getMat();
		return tot;
	}

	@Override
	public double getAverage(J15SungJukVO sj) {
//		double avg = 
//		(double)(sj.getKor() + sj.getEng() + sj.getMat()) / 3;
// 		이렇게 코드를 재사용하는 것은 비추임
		double avg = (double)getTotal(sj) / 3;
		return avg;
	}

	@Override
	public char getGrade(J15SungJukVO sj) {
		char grd = '가';
		switch( (int)getAverage(sj)/10 ){
			case 10: case 9: grd = '수'; break;
			// case 8: grd = "우"; break;
			// Type mismatch: cannot convert from String to char
			case 8: 		 grd = '우'; break;
			case 7: 		 grd = '미'; break;
			case 6: 		 grd = '양'; break;
			//default: 		 grd = '가';
		}
		return grd;
	}
	
}

class J15SungJukVO {
	private String name;
	private int kor;
	private int eng;
	private int mat;
	
	private int tot;
	private double  avg;
	private char grd;
	
	public J15SungJukVO() { }
	
	public J15SungJukVO(String name, int kor, int eng, int mat) {
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.mat = mat;
		
//		private int tot;
//		private double  avg;
//		private char grd;
		// 얘네는 계산식을 가진 메서드들 이므로 인터페이스에 정의
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMat() {
		return mat;
	}

	public void setMat(int mat) {
		this.mat = mat;
	}

	public int getTot() {
		return tot;
	}

	public void setTot(int tot) {
		this.tot = tot;
	}

	public double getAvg() {
		return avg;
	}

	public void setAvg(double avg) {
		this.avg = avg;
	}

	public char getGrd() {
		return grd;
	}

	public void setGrd(char grd) {
		this.grd = grd;
	}

	@Override
	public String toString() {
		return "J15SungJukVO [name=" + name + ", kor=" + kor + ", eng=" + eng
				+ ", mat=" + mat + ", tot=" + tot + ", avg=" + avg + ", grd="
				+ grd + "]";
	}
	
}